package org.scohen.juploadr.uploadapi;

import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.prefs.Preferences;

import org.apache.commons.codec.net.URLCodec;
import org.scohen.juploadr.app.tags.Tag;
import org.scohen.juploadr.app.tags.TagParser;
import org.scohen.juploadr.util.Persister;

public abstract class Account {
    public static final int PRIVACY_PUBLIC = 1;
    public static final int PRIVACY_PRIVATE = 2;
    public static final int PRIVACY_FRIENDS = 4;
    public static final int PRIVACY_FAMILY = 8;
    protected String name;
    protected Set<Tag> defaultTags = new LinkedHashSet<Tag>();
    protected List userTags = new LinkedList();
    protected int defaultPrivacySetting = PRIVACY_PUBLIC;
    protected boolean authenticated;
    protected URL photoURL;
    private long currentUploadUsed;
    private long monthlyUploadLimit;
    protected String username;
    protected static URLCodec codec = new URLCodec();

    public Account(String name) {
        this.name = name;
    }

    /**
     * @return Returns the authenticated.
     */
    public boolean isAuthenticated() {
        return authenticated;
    }

    /**
     * @param authenticated
     *            The authenticated to set.
     */
    public void setAuthenticated(boolean authenticated) {
        this.authenticated = authenticated;
    }

    /**
     * @return Returns the name.
     */
    public String getName() {
        return name;
    }

    /**
     * @param name
     *            The name to set.
     */
    public void setName(String name) {
        this.name = name;
    }

    public abstract ImageUploadApi getApi();

    public synchronized void save() {
        Persister<Account> p = (Persister<Account>) Persister.getInstance(getClass());
        p.persist(this);
    }

    protected void save(Preferences prefs) {
      save();

    }

    public void delete() {
        Persister<Account> p = (Persister<Account>) Persister.getInstance(getClass());
        p.remove(this);
    }

    protected static Map<String, Account> allAccountsIn(Class accountClass) {
        Persister<Account> p = (Persister<Account>) Persister.getInstance(accountClass);
        Collection<Account> allAccounts = p.loadAll();

        HashMap<String, Account> usernames = new HashMap<String, Account>();
        for (Account a : allAccounts) {
            usernames.put(a.getName(), a);
        }
        return usernames;

    }

    public long getMonthlyUploadLimit() {
        return monthlyUploadLimit;
    }

    public long getCurrentUploadUsed() {
        return currentUploadUsed;
    }

    /**
     * @param currentUploadUsed
     *            The currentUploadUsed to set.
     */
    public void setCurrentUploadUsed(long currentUploadUsed) {
        this.currentUploadUsed = currentUploadUsed;
    }

    /**
     * @param monthlyUploadLimit
     *            The monthlyUploadLimit to set.
     */
    public void setMonthlyUploadLimit(long monthlyUploadLimit) {
        this.monthlyUploadLimit = monthlyUploadLimit;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#equals(java.lang.Object)
     */
    public boolean equals(Object other) {
        if (other.getClass().equals(this.getClass())) {
            Account otherAccount = (Account) other;
            return this.getName().equals(otherAccount.getName());
        }
        return false;
    }

    /**
     * @return Returns the defaultPrivacySetting.
     */
    public int getDefaultPrivacySetting() {
        return defaultPrivacySetting;
    }

    /**
     * @param defaultPrivacySetting
     *            The defaultPrivacySetting to set.
     */
    public void setDefaultPrivacySetting(int defaultPrivacySetting) {
        this.defaultPrivacySetting = defaultPrivacySetting;
    }

    /**
     * @return Returns the defaultTags.
     */
    public Set<Tag> getDefaultTags() {
        return Collections.unmodifiableSet(defaultTags);
    }

    public void setSavedDefaultTags(String defaultTags) {
        this.defaultTags = TagParser.parse(defaultTags);
    }

    public String getSavedDefaultTags() {
        return TagParser.toInputString(defaultTags);
    }

    /**
     * @param defaultTags
     *            The defaultTags to set.
     */
    public void setDefaultTags(Set<Tag> defaultTags) {
        this.defaultTags = defaultTags;
    }

    public List getUserTags() {
        return userTags;
    }

    public void setUserTags(List userTags) {
        this.userTags = userTags;
    }

    public abstract URL getPhotoURL();

    public String getUsername() {
        return username;
    }

    /**
     * @param username
     *            The username to set.
     */
    public void setUsername(String username) {
        this.username = username;
    }
}


